home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1997 May / EnigmA AMIGA RUN 18 (1997)(G.R. Edizioni)(IT)[!][issue 1997-05][EAR-CD II].iso / earcd / util / sys / msys_1_2.lha / Src / loadwb.c < prev    next >
C/C++ Source or Header  |  1996-07-23  |  13KB  |  418 lines

  1. /*
  2. **    loadwb.c - start Workbench
  3. **    $VER: loadwb.c 42.2 (23.7.96)
  4. **    Copyright © 1996 Michal Letowski
  5. **
  6. **    42.1 (10.2.96) - initial version
  7. **    42.2 (23.7.96)
  8. **        + added RAMICON/S option
  9. */
  10.  
  11. #define __USE_SYSBASE
  12.  
  13. #include <exec/types.h>
  14. #include <exec/execbase.h>
  15. #include <exec/libraries.h>
  16. #include <exec/lists.h>
  17. #include <exec/nodes.h>
  18. #include <exec/memory.h>
  19. #include <dos/dos.h>
  20. #include <dos/dosextens.h>
  21. #include <dos/rdargs.h>
  22. #include <workbench/workbench.h>
  23. #include <support/types.h>
  24. #include <support/dos.h>
  25.  
  26. #include <proto/exec.h>
  27. #include <proto/dos.h>
  28. #include <proto/icon.h>
  29. #include <proto/wb.h>
  30.  
  31. #include "loadwb.rev.h"
  32.  
  33.  
  34. /*
  35. **    Constants
  36. */
  37. #define DOS_NAME            "dos.library"
  38. #define DOS_VERN            37L
  39. #define WB_NAME                "workbench.library"
  40. #define WB_VERN                39L
  41. #define ICON_NAME            "icon.library"
  42. #define ICON_VERN            37L
  43.  
  44. #define TEMPLATE            "DEBUG=-DEBUG/S,DELAY/S,CLEANUP/S,NEWPATH/S,HIDE/S,RAMICON/S"
  45.  
  46. #define SRC_ICON            "ENV:Sys/def_ramdisk"
  47. #define DST_ICON            "RAM:Disk"
  48.  
  49. #define WBB_DEBUG            0                                                    /* Turn on debug menu */
  50. #define WBF_DEBUG            (1<<WBB_DEBUG)
  51. #define WBB_DELAY            1                                                    /* Wait a moment after starting */
  52. #define WBF_DELAY            (1<<WBB_DELAY)
  53. #define WBB_CLEANUP        2                                                    /* Cleanup after starting */
  54. #define WBF_CLEANUP        (1<<WBB_CLEANUP)
  55. #define WBB_NEWPATH        3                                                    /* Set new Workbench path */
  56. #define WBF_NEWPATH        (1<<WBB_NEWPATH)
  57.  
  58.  
  59. /*
  60. **    Private structures
  61. */
  62. struct Options
  63. {
  64.     LBOOL opt_Debug;                                                            /* DEBUG/S */
  65.     LBOOL opt_Delay;                                                            /* DELAY/S */
  66.     LBOOL opt_CleanUp;                                                        /* CLEANUP/S */
  67.     LBOOL opt_NewPath;                                                        /* NEWPATH/S */
  68.     LBOOL opt_Hide;                                                                /* HIDE/S */
  69.     LBOOL opt_RAMIcon;                                                        /* RAMICON/S */
  70. };    /* Options */
  71.  
  72. struct PathEntry
  73. {
  74.     BPTR pe_Next;                                                                    /* Next entry */
  75.     BPTR pe_Lock;                                                                    /* Lock on directory */
  76. };    /* PathEntry */
  77.  
  78. struct MyDevNode
  79. {
  80.     struct MinNode  mdn_Node;                                            /* Link */
  81.     struct DosList *mdn_Device;                                        /* DOS device pointer */
  82. };    /* MyDevNode */
  83.  
  84.  
  85. /*
  86. **    Private macros
  87. */
  88. #define InitList(l)    ((l)->lh_Head=(struct Node *)&(l)->lh_Tail,\
  89.                                             (l)->lh_Tail=NULL,\
  90.                                             (l)->lh_TailPred=(struct Node *)&(l)->lh_Head)
  91.  
  92.  
  93. /*
  94. **    Global data
  95. */
  96. STATIC CONST TEXT VersionString[]=
  97.     VERSION(PROG_NAME,PROG_VERSION,PROG_REVISION,PROG_DATE);
  98.  
  99.  
  100. /*
  101. **    Missing WB prototypes/pragmas
  102. */
  103. LONG StartWorkbench(LONG flags, BPTR ptr);
  104.  
  105. #pragma libcall WorkbenchBase UpdateWorkbench 1e 00
  106. #pragma libcall WorkbenchBase QuoteWorkbench 24 00
  107. #pragma libcall WorkbenchBase StartWorkbench 2a 1002
  108. #pragma libcall WorkbenchBase WBConfig 54 00
  109.  
  110.  
  111. /*
  112. **    Private functions prototypes
  113. */
  114. /* Not all functions INLINED because of bug in SAS/S 6.50  */
  115. STATIC BPTR GetPathCopy(BPTR path, struct Library *DOSBase);
  116. STATIC VOID FreePathCopy(BPTR path, struct Library *DOSBase);
  117. STATIC INLINE VOID AddDosEntries(struct List *list, struct Library *DOSBase);
  118. STATIC INLINE VOID RemDosEntries(struct List *list, struct Library *DOSBase);
  119. STATIC LBOOL CopyIcon(struct Library *IconBase);
  120. STATIC INLINE LBOOL DeleteIcon(struct Library *IconBase);
  121.  
  122.  
  123. /*
  124. **    Public functions
  125. */
  126. /****** C/LoadWB ************************************************************
  127. *
  128. *   NAME
  129. *       LoadWB -- start Workbench. (V42)
  130. *
  131. *   SYNOPSIS
  132. *       LoadWB [-DEBUG] [DELAY] [CLEANUP] [NEWPATH] [HIDE] [RAMICON]
  133. *
  134. *   TEMPLATE
  135. *       LoadWB "DEBUG=-DEBUG/S,DELAY/S,CLEANUP/S,NEWPATH/S,HIDE/S,RAMICON/S"
  136. *
  137. *   FUNCTION
  138. *       This command will try to load and start Workbench. If RAMICON option
  139. *       is used, LoadWB will use 'ENV:Sys/def_ramdisk.info' icon for the
  140. *       Ram-Disk icon. If NEWPATH option is used, LoadWB will replace a
  141. *       current Workbench search path with a search path of Shell from which
  142. *       the LoadWB was issued. If Workbench is already running, the command
  143. *       will do nothing (unless NEWPATH or RAMICON option is used).
  144. *
  145. *   INPUTS
  146. *       -DEBUG  - adds 'Debug' menu to the Workbench menus. There are two
  147. *                 items under this menu:
  148. *                     'ROMWack' starts internal ROM debugger, which requires
  149. *                     a terminal to be connected to the Amiga internal serial
  150. *                     port.
  151. *                     'Flushlibs' removes all libraries, devices and fonts
  152. *                     currently not in use thus freeing some memory.
  153. *       DELAY   - forces LoadWB command not to return until Workbench is
  154. *                 completely initialized (i.e. all disk icons are loaded and
  155. *                 all WBStartup programs are started). If DELAY option does 
  156. *                 not appear, LoadWB command will return as soon as Workbench
  157. *                 is started.
  158. *       CLEANUP - forces Workbench to execute 'Clean Up' function for main
  159. *                 Workbench window after starting.
  160. *       NEWPATH - lets you change current Workbench path. Normally, Workbench
  161. *                 remembers path of the Shell that started Workbench. This
  162. *                 path is inherited by all programs strated from Workbench.
  163. *                 To change path of already running Workbench, you must use
  164. *                 NEWPATH option. If Workbench has not been started yet, this
  165. *                 option is ignored.
  166. *       HIDE    - Workbench has a habit of putting 'NDOS:???' icons for all
  167. *                 unrecognized disks. This is very annoying for users of
  168. *                 CrossDOS and DiskSpare disks. HIDE will force Workbench
  169. *                 to hide all those 'NDOS:???' icons, including the ones for
  170. *                 unformatted disks. This option also implies DELAY.
  171. *       RAMICON - changes the icon for a Ram-Disk. 'ENV:Sys/def_ramdisk.info'
  172. *                 is used to represent the new Ram-Disk icon. This option
  173. *                 can be used to set an icon for newly started Workbench
  174. *                 or to change the Ram-Disk icon of running Workbench.
  175. *                 This option also implies DELAY.
  176. *
  177. *   RESULT
  178. *       RETURN_FAIL  - if 'dos.library' or 'workbench.library' couldn't be
  179. *                      opened or command line arguments couldn't be processed.
  180. *       RETURN_ERROR - NEWPATH option was given but copy of current path
  181. *                      couldn't be made (due to lack of memory).
  182. *       RETURN_WARN  - Workbench was already running and NEWPATH option was
  183. *                      not given or RAMICON option was given and there were
  184. *                      some problems with the Ram-Disk icon.
  185. *
  186. *   EXAMPLE
  187. *       LoadWB HIDE
  188. *           ; Load Workbench, hide all 'NDOS:???' icons. Command will not
  189. *           ; return until Workbench is completely initialized.
  190. *
  191. *       LoadWB DEBUG CLEANUP
  192. *           ; Start Workbench with 'Debug' menu, move all icons after
  193. *           ; starting.
  194. *
  195. *       LoadWB NEWPATH
  196. *           ; Set path of already running Workbench or just start it.
  197. *
  198. *       LoadWB RAMICON
  199. *           ; Start Workbench and use 'ENV:Sys/def_ramdisk.info' as a
  200. *           ; Ram-Disk icon
  201. *
  202. *   NOTES
  203. *       To hide those 'NDOS:???' icons all DOS devices are removed before
  204. *       starting Workbench and restored afterwards. This might affect
  205. *       multitasking!
  206. *       RAMICON works by copying 'ENV:Sys/def_ramdisk.info' to
  207. *       'RAM:Disk.info' before Workench is started and deleting
  208. *       'RAM:Disk.info' afterwards.
  209. *       MakeLink is pure and can be made resident.
  210. *
  211. *   BUGS
  212. *       LoadWB NEWPATH sometimes hangs for a few seconds. This bug also
  213. *       appears in LoadWB 38.9 command.
  214. *
  215. *****************************************************************************
  216. *
  217. */
  218. LONG LoadWB(VOID)
  219. {
  220.     struct ExecBase *SysBase=INITSYSBASE;
  221.     struct Library *DOSBase;
  222.     struct Library *WorkbenchBase;
  223.     struct Library *IconBase=NULL;
  224.  
  225.     struct Options Opts;
  226.     struct List DevList;
  227.     struct RDArgs *Args;
  228.     struct CommandLineInterface *CLI;
  229.     APTR ConTask;
  230.     BPTR OldLock,PathLock=NULL;
  231.     LONG WBFlags=0,RC=RETURN_FAIL;
  232.     LBOOL Warn=FALSE;
  233.     
  234.     /* Open DOS */
  235.     unless(DOSBase=OpenLibrary(DOS_NAME,DOS_VERN))
  236.         throw2(SetResult2(ERROR_INVALID_RESIDENT_LIBRARY),    NO_DOS);
  237.  
  238.     /* Open Workbench */
  239.     unless(WorkbenchBase=OpenLibrary(WB_NAME,WB_VERN))
  240.         throw2(CauseIoErr(ERROR_INVALID_RESIDENT_LIBRARY,PROG_NAME),    NO_WB);
  241.  
  242.     /* Read arguments */
  243.     clear(&Opts);                                                                    /* Clear out buffer */
  244.     unless(Args=ReadArgs(TEMPLATE,(LONG *)&Opts,NULL))
  245.         throw2(PrintFault(IoErr(),PROG_NAME),    NO_ARGS);
  246.  
  247.     /* Process options */
  248.     if(Opts.opt_Debug)        fset(WBFlags,WBF_DEBUG);
  249.     if(Opts.opt_Delay)        fset(WBFlags,WBF_DELAY);
  250.     if(Opts.opt_CleanUp)    fset(WBFlags,WBF_CLEANUP);
  251.     if(Opts.opt_NewPath)    fset(WBFlags,WBF_NEWPATH);
  252.     if(Opts.opt_Hide)            fset(WBFlags,WBF_DELAY);
  253.     if(Opts.opt_RAMIcon)    fset(WBFlags,WBF_DELAY);
  254.  
  255.     RC=RETURN_OK;                                                                    /* Working for now... */
  256.  
  257.     /* Get copy of path */
  258.     if(CLI=(struct CommandLineInterface *)BADDR(ThisProcessD()->pr_CLI))
  259.         if(CLI->cli_CommandDir)
  260.             unless(PathLock=GetPathCopy(CLI->cli_CommandDir,DOSBase))
  261.             {
  262.                 PrintFault(IoErr(),PROG_NAME);
  263.                 RC=RETURN_ERROR;
  264.             }
  265.  
  266.     /* Start Workbench */
  267.     if(RC<RETURN_ERROR)                                                        /* No error copying path */
  268.     {
  269.         if(Opts.opt_RAMIcon)                                                /* RAMICON option? */
  270.         {
  271.             IconBase=OpenLibrary(ICON_NAME,ICON_VERN);
  272.             unless(CopyIcon(IconBase))                                /* Try to copy icon */
  273.                 Warn=TRUE;                                                            /* No success - set warning */
  274.         }
  275.  
  276.         InitList(&DevList);                                                    /* Set up devices list */
  277.         if(Opts.opt_Hide)                                                        /* HIDE option? */
  278.             RemDosEntries(&DevList,DOSBase);                    /* Remove all devices */
  279.  
  280.         ConTask=SetConsoleTask(NULL);                                /* No console task */
  281.         OldLock=CurrentDir(NULL);                                        /* Change to root dir */
  282.         unless(StartWorkbench(WBFlags,PathLock))        /* StartWorkbench() unsuccessfull*/
  283.         {
  284.             FreePathCopy(PathLock,DOSBase);                        /* Free path copy (if any) */
  285.             Warn=TRUE;                                                                /* Set warning flag */
  286.         }
  287.         CurrentDir(OldLock);                                                /* Change back to old dir */
  288.         SetConsoleTask(ConTask);                                        /* Restore console task */
  289.  
  290.         if(Opts.opt_Hide)                                                        /* HIDE option? */
  291.             AddDosEntries(&DevList,DOSBase);                    /* Add back all devices */
  292.  
  293.         if(Opts.opt_RAMIcon)                                                /* RAMICON option? */
  294.         {
  295.             unless(DeleteIcon(IconBase))                            /* Deletion successfull? */
  296.                 Warn=TRUE;                                                            /* No - set warning */
  297.             CloseLibrary(IconBase);                                        /* Close icon.library */
  298.         }
  299.  
  300.         /* Set result appropriately */
  301.         if(Warn)                                                                        /* Warning condition? */
  302.             RC=RETURN_WARN;                                                        /* Set result if so */
  303.     }
  304.  
  305.     /* Exceptions */
  306.     catch(NO_ARGS,    FreeArgs(Args));
  307.     catch(NO_WB,        CloseLibrary(WorkbenchBase));
  308.     catch(NO_DOS,        CloseLibrary(DOSBase));
  309.     return(RC);
  310. }    /* LoadWB */
  311.  
  312.  
  313. /*
  314. **    Private functions
  315. */
  316. STATIC BPTR GetPathCopy(BPTR path, struct Library *DOSBase)
  317. {
  318.     struct ExecBase *SysBase=INITSYSBASE;
  319.  
  320.     struct PathEntry *PE,*NewPE=NULL,*OldPE=NULL;
  321.     BPTR Result=NULL;
  322.  
  323.     /* Make a copy of each path entry */
  324.     for(PE=BADDR(path); PE; PE=BADDR(PE->pe_Next))
  325.         if(new(NewPE,MEMF_PUBCLR))
  326.         {
  327.             if(OldPE)        OldPE->pe_Next=MKBADDR(NewPE);
  328.             else                Result=MKBADDR(NewPE);
  329.             unless(NewPE->pe_Lock=DupLock(PE->pe_Lock))
  330.                 break;
  331.             OldPE=NewPE;
  332.         }
  333.  
  334.     /* Check for success */
  335.     if(!NewPE || !NewPE->pe_Lock)                                    /* AllocMem() or DupLock() error */
  336.     {
  337.         FreePathCopy(Result,DOSBase);                                /* Free alloated memory */
  338.         Result=NULL;                                                                /* Mark error */
  339.     }
  340.  
  341.     /* Return from function */
  342.     return(Result);
  343. }    /* GetPathCopy */
  344.  
  345. STATIC VOID FreePathCopy(BPTR path, struct Library *DOSBase)
  346. {
  347.     struct ExecBase *SysBase=INITSYSBASE;
  348.  
  349.     struct PathEntry *PE=BADDR(path),*OldPE;
  350.  
  351.     while(PE)
  352.     {
  353.         OldPE=PE;
  354.         PE=BADDR(PE->pe_Next);
  355.         UnLock(OldPE->pe_Lock);
  356.         delete(OldPE);
  357.     }
  358. }    /* FreePathCopy */
  359.  
  360. STATIC INLINE VOID AddDosEntries(struct List *list, struct Library *DOSBase)
  361. {
  362.     struct ExecBase *SysBase=INITSYSBASE;
  363.  
  364.     struct DosList *DL;
  365.     struct MyDevNode *MDN;
  366.  
  367.     if(DL=LockDosList(LDF_DEVICES | LDF_WRITE))        /* Lock list of DOS devices */
  368.     {
  369.         while(MDN=(struct MyDevNode *)RemHead(list))/* For each node on list */
  370.         {
  371.             if(MDN->mdn_Device)                                                /* Device pointer valid */
  372.                 AddDosEntry(MDN->mdn_Device);                        /* Add to DOS list */
  373.             delete(MDN);                                                            /* Free memory */
  374.         }
  375.         UnLockDosList(LDF_DEVICES | LDF_WRITE);            /* Unlock list of DOS devices */
  376.     }
  377. }    /* AddDosEntries */
  378.  
  379. STATIC INLINE VOID RemDosEntries(struct List *list, struct Library *DOSBase)
  380. {
  381.     struct ExecBase *SysBase=INITSYSBASE;
  382.  
  383.     struct DosList *DL;
  384.     struct MyDevNode *MDN;
  385.  
  386.     if(DL=LockDosList(LDF_DEVICES | LDF_WRITE))        /* Lock list of DOS devices */
  387.     {                                                                                            /* Locking successfull */
  388.         while(DL=NextDosEntry(DL,LDF_DEVICES))            /* For each device on list */
  389.             if(new(MDN,MEMF_PUBCLR))                                    /* Try to allocate memory for it */
  390.             {                                                                                    /* Allocation successfull */
  391.                 if(RemDosEntry(DL))                                            /* Try to remove entry */
  392.                     MDN->mdn_Device=DL;                                        /* Remember device pointer */
  393.                 AddHead(list,(struct Node *)MDN);                /* Add to list */
  394.             }
  395.         UnLockDosList(LDF_DEVICES | LDF_WRITE);            /* Unlock list of DOS devices */
  396.     }
  397. }    /* RemDosEntries */
  398.  
  399. STATIC LBOOL CopyIcon(struct Library *IconBase)
  400. {
  401.     struct DiskObject *Icon;
  402.     LBOOL RC=FALSE;
  403.  
  404.     if(IconBase)
  405.         if(Icon=GetDiskObject(SRC_ICON))
  406.             RC=PutDiskObject(DST_ICON,Icon);
  407.     return(RC);
  408. }    /* CopyIcon */
  409.  
  410. STATIC INLINE LBOOL DeleteIcon(struct Library *IconBase)
  411. {
  412.     LBOOL RC=FALSE;
  413.  
  414.     if(IconBase)
  415.         RC=DeleteDiskObject(DST_ICON);
  416.     return(RC);
  417. }    /* DeleteIcon */
  418.